"""
    Windows Package Manager - Install
"""

import configparser,os,sys,download,show,opt,shutil
import zipfile as zf

_in_dow=lambda x,y,z: None

sp="/"
instat=r"C:\Program Files\winpm"

# show.py, passing
getver=lambda x:"0.0.0"
# opt.py, passing
getconf=lambda x:None
setconf=lambda x,y,z:0
getsyscont=lambda x:""

def _vercheck(PKG, VERF):
    VERF=list(VERF)
    SYM=""
    VER=""
    VERB=0
    for C in VERF:
        if VERB: VER+=C
        elif C in ["<",">","=","!"]: 
            SYM+=C
            VERB=1
    Ver=VER.split(".")
    VerR=getver(PKG)
    Ver_=Ver.copy()
    VerR_=VerR.copy()
    if len(VerR)>len(Ver):
        for I in range(len(VerR) - len(Ver)):
            Ver_.append("0")
    else:
        for I in range(len(Ver) - len(VerR)):
            VerR_.append("0")
    Ver, VerR=Ver_.copy(), VerR_.copy()
    for T in range(len(Ver)):
        Ver[T]=int(Ver[T])
    for T in range(len(VerR)):
        VerR[T]=int(VerR[T])
    if SYM==">":
        for V in range(len(VerR)):
            if Ver[V]>VerR[V]: return False
        return True
    elif SYM==">=":
        for V in range(len(VerR)):
            if Ver[V]>=VerR[V]: return False
        return True
    elif SYM=="<":
        for V in range(len(VerR)):
            if Ver[V]<VerR[V]: return False
        return True
    elif SYM=="<=":
        for V in range(len(VerR)):
            if Ver[V]<=VerR[V]: return False
        return True
    elif SYM in ["!", "!="]:
        for V in range(len(VerR)):
            if Ver[V]!=VerR[V]: return False
        return True
    elif SYM in ["=", "=="]:
        for V in range(len(VerR)):
            if Ver[V]==VerR[V]: return False
        return True
    else:
        return False

class WinPMError(Exception):
    def __init__(self, TEXT: str):
        self.errinfo=TEXT
    def __str__(self):
        return self.errinfo


def has(conf: dict, keys: list):
    for i in keys:
        if i not in list(conf.keys()):
            raise WinPMError("No target '%s'"%i)

def read(pth):
    conf=configparser.ConfigParser()
    conf.read(pth)
    return conf

def pth(*arg):
    result=""
    for p in arg:
        result=os.path.join(result,p)
    return result

def unpack(zipf):
    with zf.Zipfile(i, "r") as ZIP:
        for j in ZIP.namelist():
            ZIP.extract(j, f"win-pm-cache{sp}")

def main(PKGN, PKGVER, mode="manual"):
    pkgn=_in_dow(PKGN, PKGVER, 1)
    return Lmain(pkgn, mode=mode)

def Lmain(PKGS: str, mode="manual"):
    for i in PKGS:
        ri=i.split(":")[0]
        if getconf(ri)!=None and mode!="manual":
            print("winpm: '%s' had already been install. Now set to manual installation"%ri)
            setconf(ri, "INSTALLATION", "manual")
            continue
        try:
            os.mkdir("win-pm-cache")
        except:pass
        unpack(i)
        os.chdir("win-pm-cache")
        i=ri
        try:
            os.chdir(i)
        except:
            sys.stderr.write("winpm: \033[91;1mE01\033[0m: Invaild WIN-PM Package format within '%s' ** \033[91mINSTALL FAILED\033[0m\nPlease check the directory structure within the package\n"%i)
            break
        try:
            config=read(pth("pkg.ini"))
        except:
            sys.stderr.write("winpm: \033[91;1mE02\033[0m: Cannot read 'pkg.ini' ** \033[91mINSTALL FAILED\033[0m\nPlease check the directory structure within the package\n")
            break
        try:
            deps=config["Dependencies"]
            conl=config["Conflicts"]
            pkgi=config["Package"]
            pNam=pkgi["Name"]
            pVer=pkgi["Version"]
            pArc=pkgi["Architecture"]
            pEpr=pkgi["ExcutePre"]
            pEpo=pkgi["ExcutePost"]
            has(pkgi,["Maintainer", "Dependencies"])
        except:
            sys.stderr.write("winpm: \033[91;1mE03\033[0m: Bad format in 'pkg.ini' ** \033[91mINSTALL FAILED\033[0m\nPlease check the config file format withon the package\n")
            break
        fail=0
        for dep in deps.keys():
            try:
                assert main(dep, deps[dep], "auto")==None
            except AssertionError:
                sys.stderr.write("winpm: \033[91;1mE04\033[0m: Install '%s' failed\n"%dep)
                fail=1
                break
        if fail: break
        fail=0
        for con in conl.keys():
            try:
                assert _vercheck(con,conl[con])
            except AssertionError:
                sys.stderr.write("winpm: \033[91;1mE05\033[0m: Version conflicts: %s"%con)
        os.system(pth("scripts",pEpr))
        install("system_driver", getsysconf("INSTALLATION"))
        install("data_driver", getsysconf("DATADRIVER"))
        os.system(pth("scripts",pEpo))
        setconf(i, "INSTALLATION", mode)
        os.chdir(pth("..",".."))
        rmrf("winpm-cache")

def install(cppath, inspath):
    os.chdir(cppath)
    for root,dirs,files in os.walk("."):
        for file in files:
            try: os.makedirs(pth(ins,root))
            except: pass
            shutil.copyfile(pth(root,file),pth(ins,root))
    os.chdir("..")

def rmrf(path):
    for root,dirs,files in os.walk(path):
        for file in files:
            try: os.remove(pth(root,file))
            except:pass
            try: os.rmdir(root)
            except:pass

